Skip to content

Conformance: test @override checks on __init__ and __new__ - #2297

Merged
rchen152 merged 3 commits into
python:mainfrom
ashishpatel26:conformance-override-init-new-2222
Aug 8, 2026
Merged

Conformance: test @override checks on __init__ and __new__#2297
rchen152 merged 3 commits into
python:mainfrom
ashishpatel26:conformance-override-init-new-2222

Conversation

@ashishpatel26

Copy link
Copy Markdown
Contributor

Closes #2222.

The @override section of the spec states that a method decorated with
@override "should [be treated] as a type error unless that method is
overriding a method or attribute in some ancestor class, and the type of the
overriding method is assignable to the type of the overridden method." There is
no exemption for __init__/__new__, so although constructors are normally
not checked against their parents, an explicit @override should still trigger
the assignability check.

This adds cases to tests/classes_override.py:

  • ChildC1: @override __init__/__new__ that are assignable to the
    parent — no error.
  • ChildC2: @override __init__/__new__ with an incompatible parameter
    type — error (# E[init], # E[new]).
  • ChildC3: incompatible __init__/__new__ without @override — allowed,
    to document the normal constructor exemption.

Scoring

Ran the conformance tool against the locked checker versions:

  • pyrefly flags the incompatible constructor overrides → conformant.
  • mypy, pyright, pycroscope, ty, zuban do not currently apply the
    assignability check to __init__/__new__ even with @override → scored
    Partial with a note.

I marked the incompatible cases as mandatory errors (# E) since the spec text
is unconditional. If maintainers feel constructor override-checking should be
left optional, these could be relaxed to # E? and the five Partial scores
returned to Pass — happy to adjust.

The @OverRide spec requires the overriding method to be assignable to the
overridden one, with no exemption for __init__/__new__. Add cases to
classes_override.py covering compatible overrides (no error), incompatible
overrides decorated with @OverRide (error), and incompatible overrides
without @OverRide (allowed). Score results: pyrefly conforms; mypy, pyright,
pycroscope, ty, and zuban do not currently honor the check for constructors.

Closes python#2222
@python-cla-bot

python-cla-bot Bot commented May 29, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@srittau srittau added the topic: conformance tests Issues with the conformance test suite label Jun 22, 2026

@jorenham jorenham left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In typeshed the object.__init__ and object.__new__ are defined as (src)

class object:
    # --snip--
    def __init__(self) -> None: ...
    def __new__(cls) -> Self: ...

Every class without base implicitly inherits from object. So does that mean that e.g.

class A:
    @override
    def __init__(self, x: int) -> None: ...

should now also be rejected? This technically indeed overrides object.__init__, but I'm not sure if reporting an error is actually useful in this case.

@JelleZijlstra

Copy link
Copy Markdown
Member

I think it should, yes. It is not a particularly useful error, but the user did put that override decorator there, so the type checker should honor it.

@rchen152
rchen152 merged commit 6a9f353 into python:main Aug 8, 2026
5 checks passed
@rchen152

rchen152 commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks @ashishpatel26!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: conformance tests Issues with the conformance test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Conformance: test that @override checks are honored for __init__ / __new__

5 participants